#include <REGX52.H>
#include <INTRINS.H>

//引脚配置
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;

//函数定义：
/*
 *@brief:延时1ms
 *@param:无
 *@retval:无
 */
void LCD_Delay()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}

//函数定义：
/*
 *@brief:LCD写命令
 *@param: Command 要写的命令
 *@retval:无
 */
void LCD_WriteCommand(unsigned char Command){
  LCD_RS=0;
	LCD_RW=0;
	P0=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/*
 *@brief:LCD写数据
 *@param: Data 要输入的数据
 *@retval:无
 */
void LCD_WriteData(unsigned char Data){
  LCD_RS=1;
	LCD_RW=0;
	P0=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/*
 *@brief:设置光标位置
 *@param: Line 行位置 范围1~2
          Column 列位置 范围1~16
 *@retval:无
 */
void LCD_SetCursor(unsigned char Line,unsigned char Column){
if(Line==1){
      LCD_WriteCommand(0x80|Column-1);
}else if(Line==2){
			LCD_WriteCommand(0x80|Column-1+0x40);
			}
 }
 
 /*
 *@brief:初始化函数
 *@param: 无
 *@retval:无
 */
 void LCD_Init(){
  LCD_WriteCommand(0x38);
	LCD_WriteCommand(0x0f);
	LCD_WriteCommand(0x06);
	LCD_WriteCommand(0x01);
 }
 
 /*
 *@brief: 在指定位置显示一个字符
 *@param: Line 列位置 范围1~2
          Column 行位置 范围1~16
					Char 要显示的字符
 *@retval:无
 */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char){
 LCD_SetCursor(Line,Column);
 LCD_WriteData(Char);
 }
 
/*
 *@brief: 在指定位置显示一个字符串
 *@param: Line 列位置 范围1~2
          Column 行位置 范围1~16
					String 要显示的字符
 *@retval:无
 */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String){
 unsigned char i;
 LCD_SetCursor(Line,Column);
 for(i=0;String[i]!='\0';i++){
    LCD_WriteData(String[i]);
 }
}

/*
 *@brief: 返回X的Y次方
 */
 int LCD_Pow(int X,int Y){
	unsigned char i;
	int result=1;
	for(i=0;i<Y;i++){
	  result*=X;
	}
	return result;
 }
 
 /*
 *@brief: 返回输入数的位数
 *@param: num 输入数字
          system 进制 
 *@retval:i 位数
 */
void LCD_Lenger(unsigned int num,unsigned char system,unsigned char *pi){
  *pi=0;
  while(num>0){
 num/=system;
 (*pi)++;
 }
}
/*
 *@brief: 在指定位置显示一个无符号数字
 *@param: Line 列位置 范围1~2
          Column 行位置 范围1~16
					Number 要显示的数字 范围0~65535
 *@retval:无
 */
 void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number){
  unsigned char i;
 LCD_SetCursor(Line,Column);
 LCD_Lenger(Number,10,&i);
	 for(;i>0;i--){
   LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
   }
 }
 
 /*
 *@brief: 在指定位置显示一个有符号数字
 *@param: Line 列位置 范围1~2
          Column 行位置 范围1~16
					Number 要显示的数字 范围-32768~32767
 *@retval:无
 */
 void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number){
 unsigned char i;
 unsigned int Number1;
 LCD_SetCursor(Line,Column);
 if(Number>=0){
   LCD_WriteData('+');
   Number1=Number;
	 }else{
	 LCD_WriteData('-');
	 Number1=-Number;
	 }
 LCD_Lenger(Number1,10,&i);
 for(;i>0;i--){
  LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
 }
}

/*
 *@brief: 在指定位置以十六进制显示一个数字
 *@param: Line 列位置 范围1~2
          Column 行位置 范围1~16
					Number 要显示的数字 范围0~0xFFFF
 *@retval:无
 */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number){
 unsigned char i,SingleNumber;
 LCD_SetCursor(Line,Column);
 LCD_Lenger(Number,16,&i);
 for(;i>0;i--){
  SingleNumber=(Number/LCD_Pow(16,i-1)%16);
	if(SingleNumber<10)
	   LCD_WriteData(SingleNumber+'0');
	else
	   LCD_WriteData(SingleNumber+'A');
 }
}

/*
 *@brief: 在指定位置以二进制显示一个数字
 *@param: Line 列位置 范围1~2
          Column 行位置 范围1~16
					Number 要显示的数字 范围0~1111 1111 1111 1111
 *@retval:无
 */
 void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number){
  unsigned char i;
	LCD_SetCursor(Line,Column);
	LCD_Lenger(Number,2,&i);
	for(;i>0;i--){
	 LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
 }